/**
 * @description: 环境处理
 * @file: env.ts
 * @author: Evan
 * @date: 2025.07.17 15:59:14
 * @week: 周四
 * @version: V
 */
import { Scene } from '../class'
import * as MD from '../data/methods'
import { useSky } from '@/hooks/sky'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'
import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js'

const { THREE, Hooks } = MD

const { skys } = useSky()

const { backgroundLoad } = Hooks.useBackground(MD.base + '/sky/', skys)

type ST = InstanceType<typeof Scene>

export function env(core: ST) {
  return {
    add() {
      const gui = core.gui
      const option = {
        bgCode: '',
        hdr: ''
      }
      const group = gui.addFolder('环境')

      // 地面
      if (core.groundMesh) {
        group.add(core.groundMesh, 'visible').name('地面')
        group.add(core.renderer.shadowMap, 'enabled').name('开启阴影')
      }

      // 渲染器
      group
        .add({ toneMapping: 'NoToneMapping' }, 'toneMapping', [
          'NoToneMapping',
          'LinearToneMapping',
          'ReinhardToneMapping',
          'CineonToneMapping',
          'ACESFilmicToneMapping',
          'AgXToneMapping',
          'NeutralToneMapping',
          'CustomToneMapping'
        ])
        .name('渲染-色调映射')
        .onChange(e => {
          // @ts-ignore
          core.renderer.toneMapping = THREE[e]
        })

      group
        .add(option, 'bgCode', skys)
        .name('背景')
        .onChange(e => {
          backgroundLoad(core, e, e === '601' ? 'png' : void 0)
        })

      group
        .add(
          option,
          'hdr',
          new Array(20)
            .fill(0)
            .map((_, index) => String(index + 1))
            .concat([
              'skidpan_2k',
              'windCab',
              'kloofendal_48d_partly_cloudy_puresky_2k',
              'moonless_golf_1k',
              'royal_esplanade_1k',
              'chapel',
              '3-1'
            ])
        )
        .name('Hdr环境')
        .onChange(e => {
          core.loadEnvTexture(`/textures/hdr/${e}.hdr`)
        })

      // @ts-ignore
      const fileEl = core.container.parentNode?.querySelectorAll(
        'input[type="file"]'
      )[1] as HTMLInputElement

      group
        .add(
          {
            importFile: () => {
              fileEl.click()
            }
          },
          'importFile'
        )
        .name('上传 hdr文件')

      group.close()
    },

    // 文件转换
    fileToEnv(file: File) {
      const filename = file.name
      const type = filename.split('.').pop()?.toLowerCase() || ''
      const reader = new FileReader()
      reader.onload = event => {
        // @ts-ignore
        const urlData = event.target.result as string
        try {
          var arr = urlData.split(',')
          // @ts-ignore
          var mime = arr[0].match(/:(.*?);/)[1] || 'image/png'
          // 去掉url的头，并转化为byte
          var bytes = window.atob(arr[1])
          // 处理异常,将ascii码小于0的转换为大于0
          var ab = new ArrayBuffer(bytes.length)
          // 生成视图（直接针对内存）：8位无符号整数，长度1个字节
          var ia = new Uint8Array(ab)

          for (var i = 0; i < bytes.length; i++) {
            ia[i] = bytes.charCodeAt(i)
          }

          const blo = new Blob([ab], {
            type: mime
          })

          const url = URL.createObjectURL(blo)

          const loader = type === 'exr' ? new EXRLoader() : new RGBELoader()

          loader.load(url, texture => {
            texture.mapping = THREE.EquirectangularReflectionMapping
            // 将加载的材质texture设置给背景和环境
            core.setEnv(texture)
          })
        } catch (e) {
          // var ab = new ArrayBuffer(0)
          // const blo = new Blob([ab], {
          //   type: 'image/png'
          // })
          console.log(e)
        }
      }
      reader.readAsDataURL(file)
    }
  }
}
